package com.itheima.stock.service.impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.itheima.stock.common.domin.StockInfoConfig;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.resp.StockExcelDomain;
import com.itheima.stock.vo.resp.PageResult;
import com.itheima.stock.vo.resp.R;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author by itheima
 * @Date 2021/12/19
 * @Description
 */
@Service("stockService")
public class StockServiceImpl implements StockService {

    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;

    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;

//    @Override
//    public List<StockBusiness> getAllStockBusiness() {
//        return stockBusinessMapper.findAll();
//    }

    /**
     * 获取国内最新大盘数据详情
     * @return
     */
    @Override
    public R<List<Map>> getInnerStockMarket() {
        //获取最近股票有效交易日，精确到分钟
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        //设置成有效数据（数据库测试数据可能不存在）
        //lastAvDate="20211228095300";
        List<Map> infos= this.stockMarketIndexInfoMapper.getInnerStockMarket(stockInfoConfig.getInner(),lastAvDate);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }

    @Override
    public R<List<Map>> getSectorAllLimit() {
        List<Map> maps=this.stockBlockRtInfoMapper.getSectorAllLimit();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据");
        }
        return R.ok(maps);
    }

    @Override
    public R<List<Map>> getStockIncrease() {
        List<Map> maps = this.stockRtInfoMapper.getStockIncrease();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据！");
        }
        return R.ok(maps);
    }

    @Override
    public R<PageResult> getStockAll(Integer page, Integer pageSize) {
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //查询
        List<Map> maps = this.stockRtInfoMapper.getStockAll();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂无数据！");
        }
        PageInfo<Map> pageInfo = new PageInfo<>(maps);
        PageResult<Map> pageResult = new PageResult<>(pageInfo);
        return R.ok(pageResult);
    }

    @Override
    public R<Map> getStockUpdownLimitCount() {
        //获取涨停统计数
        List<Map> upLimit= this.stockRtInfoMapper.getUpDownLimitCount(1);
        String curDate = DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMddHHmm"));
        if (CollectionUtils.isEmpty(upLimit)) {
            //设置默认值
            HashMap<String, Object> map = new HashMap<>();
            map.put("time",curDate);
            map.put("count",0);
            upLimit.add(map);
        }
        //获取跌停统计数
        List<Map> downLimit= this.stockRtInfoMapper.getUpDownLimitCount(0);
        if (CollectionUtils.isEmpty(upLimit)) {
            //设置默认值
            HashMap<String, Object> map = new HashMap<>();
            map.put("time",curDate);
            map.put("count",0);
            downLimit.add(map);
        }
        //组装数据
        HashMap<String, List<Map>> map = new HashMap<>();
        map.put("upList",upLimit);
        map.put("downList",downLimit);
        return R.ok(map);
    }

    @Override
    public void exportStockExcel(HttpServletResponse response, Integer page, Integer pageSize) {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        try {
            //设置响应数据格式
            response.setContentType("application/vnd.ms-excel");
            //设置编码
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("stockRt", "UTF-8");
            //设置默认文件名称
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //获取导出的分页数据
            PageHelper.startPage(page,pageSize);
            List<Map> maps = this.stockRtInfoMapper.getStockAll();
            List<StockExcelDomain> domains=new ArrayList<>();
            //转化成StockExcelDomain对象
            Gson gson = new Gson();
            maps.forEach(row->{
                StockExcelDomain domain = gson.fromJson(gson.toJsonTree(row), StockExcelDomain.class);
                domains.add(domain);
            });
            EasyExcel.write(response.getOutputStream(),StockExcelDomain.class)
                    .sheet("stockRt").doWrite(domains);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public R<Map> getStockTravolCompare() {
        //获取最近时间的一个交易日
        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //转string
        String curTStr = DateTimeUtil.parseToString4Stock(target);
        curTStr = "20220103145800";
        //T-1的日期数据
        String preTStr=DateTimeUtil.parseToString4Stock(DateTimeUtil.getPreviousTradingDay(target));
        preTStr = "20220102145800";

        //获取T日成交量数据
        List<Map> nowDatas= this.stockMarketIndexInfoMapper.getStockTravol(curTStr);
        if (CollectionUtils.isEmpty(nowDatas)) {
            nowDatas= Collections.emptyList();
        }
        //获取T-1数据
        List<Map> preDatas=this.stockMarketIndexInfoMapper.getStockTravol(preTStr);
        if (CollectionUtils.isEmpty(preDatas)) {
            preDatas=Collections.emptyList();
        }
        //组装数据
        HashMap<String, List> map = new HashMap<>();
        map.put("volList",nowDatas);
        map.put("yesVolList",preDatas);
        return R.ok(map);
    }

    @Override
    public R<Map> getStockUpdownScope() {
        //1.获取最近的有效股票交易时间，精确到分钟
        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
        String last = DateTimeUtil.getLastDateString4Stock(target);
        // 模拟数据
        last = "2022-01-06 09:55:00";
        //2.查询数据库,统计个股的涨跌幅
        List<Map> maps = stockRtInfoMapper.getStockUpDownScope(last);
        if (CollectionUtils.isEmpty(maps)) {
            maps=Collections.emptyList();
        }
        // 处理查询结果数据,将无序的涨幅区间变为有序的,如果当前区间内没有数据则填充 0
        //a.获取配置文件中涨幅区间标记
        List<String> upDownRange = stockInfoConfig.getUpDownRange();
        // 定义一个有序的list集合用于存储排序后的数据
        List<Map> newInfos = new ArrayList<>();
        for (String range : upDownRange) {
            // range: "<-7%" 、 "-7~-5%"、 "-5~-3%" 、 "-3~0%" 、"0~3%" 、 "3~5%" 、 "5~7%" 、 ">7%"
            Map orderMap = null;
            for (Map map : maps) { // {"title":"<-7","count":1}
                if (range.equals(map.get("title"))){
                    orderMap = map;
                    break;
                }
            }
            if (orderMap==null) {
                orderMap = new HashMap();
                orderMap.put("title",range);
                orderMap.put("count",0);
            }
            newInfos.add(orderMap);
        }
        //3.封装响应结果数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("time",last);
        map.put("infos",newInfos);
        return R.ok(map);
    }

    @Override
    public R<List<Map>> getStockScreenMinuteSharing(String stockCode) {

        String tDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        tDate ="2022-01-06 09:55:00";
        List<Map> infos = stockRtInfoMapper.getStockScreenMinuteSharing(stockCode,tDate);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }

    @Override
    public R<List<Map>> getDayKLinData(String stockCode) {
        DateTime hisDate = DateTime.now().minusDays(20);
        //获取日期字符串
        String hisDateStr=hisDate.toString(DateTimeFormat.forPattern("yyyyMMdd"));
        hisDateStr ="2022-01-06 09:55:00";
        List<Map> infos= this.stockRtInfoMapper.getDayKLinData(stockCode,hisDateStr);
        if (CollectionUtils.isEmpty(infos)) {
            return R.error("暂无数据");
        }
        return R.ok(infos);
    }
}